
package com.whz.generic.api;

import com.fasterxml.jackson.core.type.TypeReference;
import com.whz.generic.api.exception.CommonBusinessException;
import com.whz.generic.json.JacksonUtils;
import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

import java.util.Objects;
import java.util.function.Function;

/**
 * @author whz
 */
@Slf4j
@UtilityClass
public class ApiResponseUtils {

    /**
     * 校验API是否正常返回response
     *
     * @param response api返回封装
     * @param <T>      参数类型
     * @return true 接口调用成功
     */
    public static <T> boolean isSuccess(ApiResponseWrapper<T> response) {
        return response != null && response.ok();
    }

    /**
     * 校验API是否返回有效数据
     *
     * @param response api返回封装
     * @param <T>      参数类型
     * @return true 接口调用成功,返回有效数据
     */
    public static <T> boolean isPayLoadNull(ApiResponseWrapper<T> response) {
        return isSuccess(response) && Objects.nonNull(response.getPayLoad());
    }


    /**
     * 获取api返回数据或者Null
     *
     * @param response api返回封装
     * @param <T>      参数类型
     * @return api返回数据
     */
    public static <T> T getPayloadOrNull(ApiResponseWrapper<T> response) {
        return isPayLoadNull(response)? response.getPayLoad() : null;
    }

    /**
     * 获取api返回数据,或者抛出异常
     *
     * @param response api返回封装
     * @param <T>      参数类型
     * @return api返回数据
     */
    public static <T> T payLoadOrException(ApiResponseWrapper<T> response) {
        if (isPayLoadNull(response)) {
            return response.getPayLoad();
        }
        throw new CommonBusinessException.Builder()
                .create()
                .code(500)
                .messageFileName(response.getError())
                .build();
    }

    /**
     * 执行API function 返回ApiTongyuResponse类型装类体
     *
     * @param param    API入参
     * @param function api函数
     * @param <T>      参数类型
     * @param <R>      返回类型
     * @return ApiTongyuResponse类型装类体
     */
    public static <T, R> ApiResponseWrapper<R> getApiResponse(T param, Function<T, R> function) {
        try {
            return ApiResponseWrapper.success(function.apply(param));
        } catch (Exception e) {
            log.error("Execute Api Function Error.", e);
            return ApiResponseWrapper.whenFail(e.getMessage());
        }
    }

    /**
     * 执行API function 返回ApiTongyuResponse类型装类体
     *
     * @param param    API入参
     * @param function api函数
     * @param <T>      参数类型
     * @param <R>      返回类型
     * @return ApiTongyuResponse类型装类体
     */
    public static <T, R> ApiResponseWrapper<R> safeExecute(T param, Function<T, ApiResponseWrapper<R>> function) {
        try {
            return function.apply(param);
        } catch (Exception e) {
            log.error("Execute Api Function Error.", e);
            return ApiResponseWrapper.whenFail(e.getMessage());
        }
    }

    @SneakyThrows
    public static <T> ApiResponseWrapper<T> parseToApiResponseWrapper(String json) {
        return JacksonUtils.MAPPER.readValue(json, new TypeReference<ApiResponseWrapper<T>>() {
        });
    }
}